﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework.Input;
using System.Windows.Graphics;
using Microsoft.Xna.Framework.Graphics;

namespace XnaCanvas {
    public partial class XCanvas : UserControl {
        public XCanvas() {
            InitializeComponent();
            Initialusercom();
        }
        System.Threading.SynchronizationContext fSynchronizationContext;
        XSence baseSence;
        public XTrigger Trigger { get; private set; }
        private void Initialusercom() {
            var rc = Application.Current.RootVisual as Control;
            if (rc != null) {
                rc.KeyDown += this.rc_KeyDown;
                rc.KeyUp += this.rc_KeyUp;
            }
            this.IsRun = false;
            this.Children = new List<XSence>();
            this.baseSence = new XSence();
            this.Trigger = new XTrigger(this);
            this.Children.Add(baseSence);
            this.Trigger.Csn = 0;
            this.ExitKey = this.ExitKey ?? Key.Escape;
            this.fSynchronizationContext = System.Threading.SynchronizationContext.Current;
        }

        #region base event anwser
        private void UserControl_Loaded(object sender, RoutedEventArgs e) {

        }
        void rc_KeyUp(object sender, KeyEventArgs e) {
            this.Trigger.CurrentKey = e.Key;
            this.Trigger.IsKeyDown = true;
        }

        void rc_KeyDown(object sender, KeyEventArgs e) {
            this.Trigger.CurrentKey = e.Key;
            this.Trigger.IsKeyDown = false;
        }
        private void UserControl_MouseEnter(object sender, MouseEventArgs e) {
            this.Trigger.IsMouseEnter = true;
        }

        private void UserControl_MouseLeave(object sender, MouseEventArgs e) {
            this.Trigger.IsMouseEnter = false;
        }

        private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            this.Trigger.IsMouseLeftButtonDown = true;
        }

        private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
            this.Trigger.IsMouseLeftButtonDown = false;
        }
        private void UserControl_MouseMove(object sender, MouseEventArgs e) {
            var p = e.GetPosition(this);
            this.Trigger.SetMouseLocation(p);
        }

        private void UserControl_MouseRightButtonDown(object sender, MouseButtonEventArgs e) {
            this.Trigger.IsMouseRightButtonDown = true;
        }

        private void UserControl_MouseRightButtonUp(object sender, MouseButtonEventArgs e) {
            this.Trigger.IsMouseRightButtonDown = false;
        }
        #endregion
        #region function
        bool IsRun;
        public void End() {
            this.fSynchronizationContext.Post(sopc => {
                this.DrawingSurface.Draw -= this.Drawing; IsRun = false;
            }, null);
        }
        public void Begin() {
            if (!IsRun) {
                this.Trigger.CurrentKey = Key.None;
                this.DrawingSurface.Draw += this.Drawing;
                this.DrawingSurface.Invalidate(); IsRun = true;
            }
        }
        private void Drawing(object sender, DrawEventArgs e) {
            XSence.Device.Clear(this.xBackground);
            this.Children[this.Trigger.Csn].Apply();
            this.Trigger.DeltaTime = e.DeltaTime;
            this.Trigger.TotalTime = e.TotalTime;
            XSence.Device.RasterizerState = Trigger.rs;
            if (this.Trigger.CurrentKey == ExitKey) {
                XSence.Device.Clear(Microsoft.Xna.Framework.Color.Transparent);
                this.End();
            } else {
                e.InvalidateSurface();
            }
        }
        Microsoft.Xna.Framework.Color xBackground;
        public Microsoft.Xna.Framework.Color XBackground {
            get { return xBackground; }
            set { xBackground = value; }
        }
        public List<XSence> Children { get; set; }
        public new Brush Background {
            get { return base.Background; }
            set {
                base.Background = value;
                var scb = this.Background as SolidColorBrush;
                if (scb != null) {
                    this.xBackground.R = scb.Color.R;
                    this.xBackground.G = scb.Color.G;
                    this.xBackground.B = scb.Color.B;
                    this.xBackground.A = scb.Color.A;
                }
            }
        }
        #endregion
        public Key? ExitKey { get; set; }
    }
}
